package com.suray.wcs.service.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.suray.commin.core.utils.SurayBeanUtils;
import com.suray.wcs.service.system.bo.PageResultBO;
import com.suray.wcs.service.system.bo.ZoneRuleBO;
import com.suray.wcs.service.system.entity.NodeDB;
import com.suray.wcs.service.system.entity.ZoneRuleDB;
import com.suray.wcs.service.system.mapper.NodeDBMapper;
import com.suray.wcs.service.system.mapper.ZoneRuleMapper;
import com.suray.wcs.service.system.service.IZoneRuleService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 12419
 * @title: ZoneRuleServiceImpl
 * @projectName web_dev
 * @description: TODO
 * @date 2021/1/2911:15
 */
@Service
public class ZoneRuleServiceImpl extends ServiceImpl<ZoneRuleMapper, ZoneRuleDB> implements IZoneRuleService {
    @Resource
    private ZoneRuleMapper zoneRuleMapper;
    @Resource
    private NodeDBMapper nodedbMapper;

    @Override
    public List<ZoneRuleDB> getZoneRuleList(Integer x, Integer y, Integer z) {
        QueryWrapper<ZoneRuleDB> queryWrapper = new QueryWrapper();
        if (x != null) {
            queryWrapper.lambda().le(ZoneRuleDB::getGridxStart, x).ge(ZoneRuleDB::getGridxEnd, x);
        }
        if (y != null) {
            queryWrapper.lambda().le(ZoneRuleDB::getGridyStart, y).ge(ZoneRuleDB::getGridyEnd, y);
        }
        if (z != null) {
            queryWrapper.and(wrapper -> wrapper.lambda().like(ZoneRuleDB::getGridz, "," + z + ",")
                    .or().like(ZoneRuleDB::getGridz, "," + z + "]")
                    .or().like(ZoneRuleDB::getGridz, "[" + z + ",")
                    .or().like(ZoneRuleDB::getGridz, "[" + z + "]")
            );
        }
        queryWrapper.orderByDesc("rule_id");
        List<ZoneRuleDB> ZoneRuleDBS = zoneRuleMapper.selectList(queryWrapper);

        return ZoneRuleDBS;
    }

    @Override
    public ZoneRuleBO addZoneRule(ZoneRuleBO zoneRuleBO) {

        ZoneRuleDB zoneRuleDB = SurayBeanUtils.copyProperties(zoneRuleBO, ZoneRuleDB.class);
        zoneRuleDB.setGridz(JSON.toJSONString(zoneRuleBO.getGridzList()));
        zoneRuleDB.setCreateTime(new Date());
        zoneRuleMapper.insert(zoneRuleDB);
        return zoneRuleBO;
    }

    @Override
    public boolean checkZoneRuleName(ZoneRuleBO zoneRuleBO) {
        QueryWrapper<ZoneRuleDB> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ZoneRuleDB::getName, zoneRuleBO.getName());
        List<ZoneRuleDB> zoneRuleDBS = zoneRuleMapper.selectList(queryWrapper);
        if (zoneRuleDBS != null && zoneRuleDBS.size() > 0) {
            return true;
        }
        return false;
    }

    @Override
    public ZoneRuleBO updateZoneRule(ZoneRuleBO zoneRuleBO) {
        ZoneRuleDB zoneRuleDB = SurayBeanUtils.copyProperties(zoneRuleBO, ZoneRuleDB.class);
        zoneRuleDB.setGridz(JSON.toJSONString(zoneRuleBO.getGridzList()));
        zoneRuleDB.setUpdateTime(new Date());
        zoneRuleMapper.updateById(zoneRuleDB);
        return zoneRuleBO;
    }

    // 返回去重复后的姓名列表
    @Override
    public List<ZoneRuleBO> getZoneNameList() {
        List<ZoneRuleBO> zoneRuleBOs = ZoneRuleBO.getZoneRuleBOListByDB(zoneRuleMapper.selectList(null));
        //List<String> zoneRuleDBSNameList = zoneRuleDBS.stream().map( i -> i.getName()).distinct().collect(Collectors.toList());
        return zoneRuleBOs;
    }

    @Override
    public void deleteZoneRule(List<Integer> ids) {
        zoneRuleMapper.deleteBatchIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applyZoneRule(List<Integer> ids) {
        List<ZoneRuleDB> zoneRuleDBS = zoneRuleMapper.selectBatchIds(ids);
        zoneRuleDBS.sort((a, b) -> a.getRuleId() - b.getRuleId());
        for (ZoneRuleDB zoneRuleDB : zoneRuleDBS) {
            QueryWrapper<NodeDB> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().ge(NodeDB::getGridx, zoneRuleDB.getGridxStart()).le(NodeDB::getGridx, zoneRuleDB.getGridxEnd())
                    .ge(NodeDB::getGridy, zoneRuleDB.getGridyStart()).le(NodeDB::getGridy, zoneRuleDB.getGridyEnd())
                    .in(NodeDB::getGridz, JSONArray.parseArray(zoneRuleDB.getGridz(), Integer.class));
            List<NodeDB> nodeDBS = nodedbMapper.selectList(queryWrapper);
            if (CollectionUtils.isNotEmpty(nodeDBS)) {
                for (NodeDB nodeDB : nodeDBS) {
                    NodeDB newNodeDB = new NodeDB();
                    newNodeDB.setNodeId(nodeDB.getNodeId());
                    if (zoneRuleDB.getRuleId() != null) {
                        newNodeDB.setZoneId(zoneRuleDB.getRuleId());
                    }
                    nodedbMapper.updateById(newNodeDB);
                }
            }
        }
    }
}
